package droidninja.filepicker.utils;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import droidninja.filepicker.models.MediaResult;

/**
 * Created by droidNinja on 29/07/16.
 */
public class FilePickerUtils {

    public static <T> Collection<T> filter(Collection<T> target, Predicate<T> predicate) {
        Collection<T> result = new ArrayList<T>();
        for (T element : target) {
            if (predicate.apply(element)) {
                result.add(element);
            }
        }
        return result;
    }

    public static String getFileExtension(File file) {
        String name = file.getName();
        try {
            return name.substring(name.lastIndexOf(".") + 1);
        } catch (Exception e) {
            return "";
        }
    }

    public static boolean contains(String[] types, String path) {
        for (String string : types) {
            if (path.toLowerCase().endsWith(string)) return true;
        }
        return false;
    }

    public static void notifyMediaStore(final Context context, final List<String> pathList, MediaResult.OnMediaResultListener listener) {
        if (pathList == null || pathList.isEmpty()) {
            if (listener != null) {
                listener.onMediaResult(null);
            }
            return;
        }
        List<String> useList = new ArrayList<>();
        for (String path : pathList) {
            if (FileUtils.isFileExists(context, path)) {
                useList.add(path);
            }
        }
        if (useList.isEmpty()) {
            if (listener != null) {
                listener.onMediaResult(null);
            }
            return;
        }
        // 最后通知图库更新
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 判断SDK版本是不是4.4或者高于4.4
            FilePickerUtils.notifyMediaStoreR(context, useList, listener);
        } else {
            for (String path : useList) {
                final Intent intent;
                File file = new File(path);
                if (file.isDirectory()) {
                    intent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
                    intent.setClassName("com.android.providers.media", "com.android.providers.media.MediaScannerReceiver");
                    intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
                } else {
                    intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    intent.setData(Uri.fromFile(file));
                }
                context.sendBroadcast(intent);
            }
            if (listener != null) {
                listener.onMediaResult(new MediaResult(useList));
            }
        }
    }

    /**
     * 通知系统扫描文件
     *
     * @param context  上下文
     * @param pathList 要扫描的文件
     * @return
     */
    public static void notifyMediaStoreR(Context context, final List<String> pathList, MediaResult.OnMediaResultListener listener) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 判断SDK版本是不是4.4或者高于4.4
            String path = pathList.get(0);
            if (FileUtils.isImageFile(path)) {
                notifyImage(context, pathList, listener);
            } else if (FileUtils.isVideoFile(path)) {
                notifyVideo(context, pathList, listener);
            } else if (FileUtils.isAudioFile(path)) {
                notifyAudio(context, pathList, listener);
            } else {
                String[] objects = pathList.toArray(new String[]{});
                MediaScannerConnection.scanFile(context, objects, null, new MediaScannerConnection.MediaScannerConnectionClient() {
                    @Override
                    public void onMediaScannerConnected() {
                    }

                    @Override
                    public void onScanCompleted(String path, Uri uri) {
                        if (listener != null) {
                            listener.onMediaResult(new MediaResult(pathList));
                        }
                    }
                });
            }
        } else {
            for (String path : pathList) {
                final Intent intent;
                File file = new File(path);
                if (file.isDirectory()) {
                    intent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
                    intent.setClassName("com.android.providers.media", "com.android.providers.media.MediaScannerReceiver");
                    intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
                } else {
                    intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    intent.setData(Uri.fromFile(file));
                }
                context.sendBroadcast(intent);
            }
            if (listener != null) {
                listener.onMediaResult(new MediaResult(pathList));
            }
        }
    }

    /**
     * 将图片保存到系统相册
     */
    public static void notifyImage(Context context, final List<String> pathList, MediaResult.OnMediaResultListener listener) {
        ContentResolver localContentResolver = context.getContentResolver();
        runIo(new Runnable() {
            @Override
            public void run() {
                List<Uri> uriList = new ArrayList<>();
                for (String path : pathList) {
                    File file = new File(path);
                    ContentValues localContentValues = getImageContentValues(file, System.currentTimeMillis());
                    Uri uri = localContentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, localContentValues);
                    if (uri != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
                            context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
                        //拷贝文件到相册的uri,android11及以上得这么干，否则不会显示。可以参考ScreenMediaRecorder的save方法
                        OutputStream os = null;
                        try {
                            os = localContentResolver.openOutputStream(uri, "w");
                            Files.copy(file.toPath(), os);
                            file.deleteOnExit();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            if (os != null) {
                                try {
                                    os.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    if (uri != null) {
                        uriList.add(uri);
                    }
                }
                runMain(new Runnable() {
                    @Override
                    public void run() {
                        for (Uri uri : uriList) {
                            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
                        }
                        if (listener != null) {
                            listener.onMediaResult(new MediaResult(true, pathList));
                        }
                    }
                });
            }
        });
    }

    /**
     * 将视频保存到系统相册
     */
    public static void notifyVideo(Context context, List<String> pathList, MediaResult.OnMediaResultListener listener) {
        ContentResolver localContentResolver = context.getContentResolver();
        runIo(new Runnable() {
            @Override
            public void run() {
                List<Uri> uriList = new ArrayList<>();
                for (String path : pathList) {
                    File file = new File(path);
                    ContentValues localContentValues = getVideoContentValues(file, System.currentTimeMillis());
                    Uri uri = localContentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, localContentValues);
                    if (uri != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
                            context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
                        //拷贝文件到相册的uri,android11及以上得这么干，否则不会显示。可以参考ScreenMediaRecorder的save方法
                        OutputStream os = null;
                        try {
                            os = localContentResolver.openOutputStream(uri, "w");
                            Files.copy(file.toPath(), os);
                            file.deleteOnExit();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            if (os != null) {
                                try {
                                    os.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    if (uri != null) {
                        uriList.add(uri);
                    }
                }
                runMain(new Runnable() {
                    @Override
                    public void run() {
                        for (Uri uri : uriList) {
                            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
                        }
                        if (listener != null) {
                            listener.onMediaResult(new MediaResult(true, pathList));
                        }
                    }
                });
            }
        });

    }

    /**
     * 将视频保存到系统相册
     */
    public static void notifyAudio(Context context, List<String> pathList, MediaResult.OnMediaResultListener listener) {
        ContentResolver localContentResolver = context.getContentResolver();
        runIo(new Runnable() {
            @Override
            public void run() {
                List<Uri> uriList = new ArrayList<>();
                for (String path : pathList) {
                    File file = new File(path);
                    ContentValues localContentValues = getAudioContentValues(file, System.currentTimeMillis());
                    Uri uri = localContentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, localContentValues);
                    if (uri != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
                            context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
                        //拷贝文件到相册的uri,android11及以上得这么干，否则不会显示。可以参考ScreenMediaRecorder的save方法
                        OutputStream os = null;
                        try {
                            os = localContentResolver.openOutputStream(uri, "w");
                            Files.copy(file.toPath(), os);
                            file.deleteOnExit();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            if (os != null) {
                                try {
                                    os.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    if (uri != null) {
                        uriList.add(uri);
                    }
                }
                runMain(new Runnable() {
                    @Override
                    public void run() {
                        for (Uri uri : uriList) {
                            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
                        }
                        if (listener != null) {
                            listener.onMediaResult(new MediaResult(true, pathList));
                        }
                    }
                });
            }
        });
    }

    /**
     * 获取图片的ContentValue
     */
    public static ContentValues getImageContentValues(File paramFile, long timestamp) {
        ContentValues localContentValues = new ContentValues();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            localContentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/Camera");
        }
        localContentValues.put(MediaStore.Images.Media.TITLE, paramFile.getName());
        localContentValues.put(MediaStore.Images.Media.DISPLAY_NAME, paramFile.getName());
        localContentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        localContentValues.put(MediaStore.Images.Media.DATE_TAKEN, timestamp);
        localContentValues.put(MediaStore.Images.Media.DATE_MODIFIED, timestamp);
        localContentValues.put(MediaStore.Images.Media.DATE_ADDED, timestamp);
        localContentValues.put(MediaStore.Images.Media.ORIENTATION, 0);
        localContentValues.put(MediaStore.Images.Media.DATA, paramFile.getAbsolutePath());
        localContentValues.put(MediaStore.Images.Media.SIZE, paramFile.length());
        return localContentValues;
    }

//    private static void copyFileAfterQ(Context context, ContentResolver localContentResolver,
//                                       File tempFile, Uri localUri, MediaResult.OnMediaResultListener listener) {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
//                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
//            if (isMainThread()) {
//                new Thread() {
//                    @Override
//                    public void run() {
//                        boolean isSuccessFul = false;
//                        OutputStream os = null;
//                        try {
//                            os = localContentResolver.openOutputStream(localUri, "w");
//                            Files.copy(tempFile.toPath(), os);
//                            tempFile.deleteOnExit();
//                            isSuccessFul = true;
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                            isSuccessFul = false;
//                        } finally {
//                            if (os != null) {
//                                try {
//                                    os.close();
//                                } catch (IOException e) {
//                                    e.printStackTrace();
//                                }
//                            }
//                            boolean finalIsSuccessFul = isSuccessFul;
//                            new Handler(Looper.getMainLooper()).post(new Runnable() {
//                                @Override
//                                public void run() {
//                                    if (listener != null) {
//                                        listener.onMediaResult(new MediaResult(finalIsSuccessFul, tempFile.getAbsolutePath()));
//                                    }
//                                }
//                            });
//                        }
//                    }
//                }.start();
//                return;
//            }
//            boolean isSuccessFul = false;
//            //拷贝文件到相册的uri,android11及以上得这么干，否则不会显示。可以参考ScreenMediaRecorder的save方法
//            OutputStream os = null;
//            try {
//                os = localContentResolver.openOutputStream(localUri, "w");
//                Files.copy(tempFile.toPath(), os);
//                tempFile.deleteOnExit();
//                isSuccessFul = true;
//            } catch (IOException e) {
//                e.printStackTrace();
//                //noinspection ReassignedVariable
//                isSuccessFul = false;
//            } finally {
//                if (os != null) {
//                    try {
//                        os.close();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
//                boolean finalIsSuccessFul = isSuccessFul;
//                new Handler(Looper.getMainLooper()).post(new Runnable() {
//                    @Override
//                    public void run() {
//                        if (listener != null) {
//                            listener.onMediaResult(new MediaResult(finalIsSuccessFul, tempFile.getAbsolutePath()));
//                        }
//                    }
//                });
//
//            }
//        }
//    }


    /**
     * 获取视频的contentValue
     */
    public static ContentValues getVideoContentValues(File paramFile, long timestamp) {
        ContentValues localContentValues = new ContentValues();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            localContentValues.put(MediaStore.Video.Media.RELATIVE_PATH, "DCIM/Camera");
        }
        localContentValues.put(MediaStore.Video.Media.TITLE, paramFile.getName());
        localContentValues.put(MediaStore.Video.Media.DISPLAY_NAME, paramFile.getName());
        localContentValues.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
        localContentValues.put(MediaStore.Video.Media.DATE_TAKEN, timestamp);
        localContentValues.put(MediaStore.Video.Media.DATE_MODIFIED, timestamp);
        localContentValues.put(MediaStore.Video.Media.DATE_ADDED, timestamp);
        localContentValues.put(MediaStore.Video.Media.DATA, paramFile.getAbsolutePath());
        localContentValues.put(MediaStore.Video.Media.SIZE, paramFile.length());
        return localContentValues;
    }

    /**
     * 获取音频的contentValue
     */
    public static ContentValues getAudioContentValues(File paramFile, long timestamp) {
        ContentValues localContentValues = new ContentValues();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            localContentValues.put(MediaStore.Audio.Media.RELATIVE_PATH, "DCIM/Camera");
        }
        localContentValues.put(MediaStore.Audio.Media.TITLE, paramFile.getName());
        localContentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, paramFile.getName());
        localContentValues.put(MediaStore.Audio.Media.MIME_TYPE, "video/mp4");
        localContentValues.put(MediaStore.Audio.Media.DATE_TAKEN, timestamp);
        localContentValues.put(MediaStore.Audio.Media.DATE_MODIFIED, timestamp);
        localContentValues.put(MediaStore.Audio.Media.DATE_ADDED, timestamp);
        localContentValues.put(MediaStore.Audio.Media.DATA, paramFile.getAbsolutePath());
        localContentValues.put(MediaStore.Audio.Media.SIZE, paramFile.length());
        return localContentValues;
    }

    public static boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }

    public static void runIo(Runnable runnable) {
        if (isMainThread()) {
            new Thread(runnable).start();
            return;
        }
        runnable.run();
    }

    public static void runMain(Runnable runnable) {
        if (isMainThread()) {
            runnable.run();
            return;
        }
        new Handler(Looper.getMainLooper()).post(runnable);
    }
}
